﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Sql;
using System.Data;
using System.Data.SqlClient;
using System.Security.Cryptography;
using Hosting.Class;
using System.Text.RegularExpressions;
using System.Data.Linq;


namespace Hosting.Class
{
    public class Users
    {

        private HostingDomainWebsiteDataContext db = new HostingDomainWebsiteDataContext();

        public Users() { }

        #region [Check Login is success or not]
        /// <summary>
        /// Check Login is success or not
        /// </summary>
        /// <param name="username">The name for login</param>
        /// <param name="password">The code for login</param>
        /// <returns>
        /// <para>0     : Username or Password is not correct!</para>
        /// <para>1     : Login successfully</para>
        /// <para>2     : Your account has been blocked!</para>
        /// <para>-99   : error</para>
        /// </returns>
        public int isLogin(string username, string password)
        {
            try 
            {
                HostingDomainWebsiteDataContext db = new HostingDomainWebsiteDataContext();

                var users = db.PC_Users_Login(username);

                foreach (var u in users)
                {
                    if (username.Equals(u.UserName))
                    {
                        using (MD5 md5Hash = MD5.Create())
                        {
                            SecurityHash secure = new SecurityHash();
                            if (secure.VerifyMd5Hash(md5Hash, password, u.PassWord))
                            {
                                if (u.Active == true)
                                {
                                    return 1;
                                }
                                else
                                {
                                    return 2;
                                }
                            }
                        }
                    }
                }
                return 0;
            }
            catch(Exception ex)
            {
                return -99;
            }

        }
        #endregion

        #region [Add a new User]
        /// <summary>
        /// Add a new User
        /// </summary>
        /// <param name="username">The name for login</param>
        /// <param name="password">The code for login</param>
        /// <param name="phone">The number phone of user</param>
        /// <param name="email">The email of user</param>
        /// <param name="address">The address of user</param>
        /// <returns>
        /// <para>0     : Success</para>
        /// <para>-99   : error</para>
        /// </returns>
        public int Add(string username, string password, string phone, string email, string address)
        {
            try
            {
                string hash = password;
                using (MD5 md5Hash = MD5.Create())
                {
                    SecurityHash secure = new SecurityHash();
                    hash = secure.GetMd5Hash(md5Hash, password);
                }
                int isInsert = db.PC_Users_Ins(username, hash, email, phone, address, true);
                return isInsert;
            }
            catch (Exception e)
            {
                db.Dispose();
                return -99;
            }
        }
        #endregion

        /* Return:
         *   0  : Success
         * -99  : error
         */
        public int Edit(string username ,string email, string phone, string address, bool active)
        {
            try
            {
                int isUpdate = db.PC_Users_Upd_Info(username, email, phone, address, active);
                return isUpdate;
            }
            catch(Exception ex)
            {
                return -99;
            }
        }

        public bool isUsernameExist(string username)
        {
            var check = db.PC_UsersShow_GetOne(username).ToList();

            if (check.Count > 0)
            {
                return true;
            }

            return false;
        }

        /* addValid() method return:
         * 1    : Validation is successful!
         * 10   : Username input is null or not have value
         * 11   : Username is less than 5 character
         * 12   : Username is greater than 50 character
         * 13   : Username is have an special character, Valid: [a-zA-Z0-9]
         * 14   : Username is existed
         * 20   : Password input is null or not have value
         * 21   : Password is less than 8 character
         * 22   : Password is greater than 100 character
         * 23   : Password is not valid, Valid: [a-zA-Z0-9@!#$\'%^&*`~]
         * 24   : Password and repassword is not match
         * 30   : Email is not valid
         * 31   : Email is too big
         * 40   : Phone is null or not have value
         * 41   : Phone must be number
         * 42   : Phone is less than 10 character
         * 43   : Phone is greater than 15 character
         * 50   : Address is too long
         */
        #region [Check insert is valid or not]
        /// <summary>
        /// 
        /// </summary>
        /// <param name="username">The name for login</param>
        /// <param name="password">The code for login</param>
        /// <param name="repassword">The re-code to check code for login</param>
        /// <param name="phone">The number phone of user</param>
        /// <param name="email">The email of user</param>
        /// <param name="address">The address of user</param>
        /// <returns></returns>
        public int addValid(string username, string password, string repassword, string phone, string email, string address)
        {
            /*USERNAME*/

            if (String.IsNullOrEmpty(username))
            {
                return 10;
            }
            else if(username.Length < 5)
            {
                return 11;
            }
            else if (username.Length > 50)
            {
                return 12;
            }
            Regex rUsernameSpec = new Regex(@"[a-zA-Z0-9]{5,50}");
            Match mUsernameSpec = rUsernameSpec.Match(username);
            if (!mUsernameSpec.Success)
            {
                return 13;
            }
            else if (isUsernameExist(username))
            {
                return 14;
            }

            /*PASSWORD*/

            if (String.IsNullOrEmpty(password))
            {
                return 20;
            }            
            else if (password.Length < 8)
            {
                return 21;
            }
            else if (password.Length > 50)
            {
                return 22;
            }

            Regex rPasswordValid = new Regex(@"[a-zA-Z0-9@!#$\'%^&*`~]{0,100}");
            Match mPasswordValid = rPasswordValid.Match(password);
            if (!mPasswordValid.Success)
            {
                return 23;
            }
            else if(!password.Equals(repassword))
            {
                return 24;
            }

            /*EMAIL*/

            if (String.IsNullOrEmpty(email))
            {
                return 30;
            }

            Regex rEmailValid = new Regex(@"^[-!#$%&'*+/0-9=?A-Z^_a-z{|}~](\.?[-!#$%&'*+/0-9=?A-Z^_a-z{|}~])*@[a-zA-Z](-?[a-zA-Z0-9])*(\.[a-zA-Z](-?[a-zA-Z0-9])*)+${0,100}");
            Match mEmailValid = rEmailValid.Match(email);
            if (!mEmailValid.Success)
            {
                return 31;
            }

            /*Phone*/
            

            if (String.IsNullOrEmpty(phone))
            {
                return 40;
            }

            Regex rPhoneValid = new Regex(@"^[0-9]{0,}$");
            Match mPhoneValid = rPhoneValid.Match(phone);
            if (!mPhoneValid.Success)
            {
                return 41;
            }
            else if (phone.Length < 10)
            {
                return 42;
            }
            else if (phone.Length > 15)
            {
                return 43;
            }

            /*Address*/
            else if (address.Length > 2000)
            {
                return 50;
            }

            return 1;
        }
        #endregion

        /* 30  : Email is not valid
         * 31   : Email is too big
         * 40   : Phone is null or not have value
         * 41   : Phone must be number
         * 42   : Phone is less than 10 character
         * 43   : Phone is greater than 15 character
         * 50   : Address is too long
          */
        #region [Check Update is valid or not]
        /// <summary>
        /// Check Update is valid or not
        /// </summary
        /// <param name="email">The email of user</param>
        /// <param name="phone">The number phone of user</param>
        /// <param name="address">The address of user</param>
        /// <returns></returns>
        public int editValid(string email, string phone, string address)
        {

            /*Phone*/            

            if (String.IsNullOrEmpty(phone))
            {
                return 40;
            }
            Regex rPhoneValid = new Regex(@"^[0-9]*$");
            Match mPhoneValid = rPhoneValid.Match(phone);
            if (!mPhoneValid.Success)
            {
                return 41;
            }
            else if (phone.Length < 10)
            {
                return 42;
            }
            else if (phone.Length > 15)
            {
                return 43;
            }

            /*EMAIL*/
            
            if (String.IsNullOrEmpty(email))
            {
                return 30;
            }

            Regex rEmailValid = new Regex(@"^[-!#$%&'*+/0-9=?A-Z^_a-z{|}~](\.?[-!#$%&'*+/0-9=?A-Z^_a-z{|}~])*@[a-zA-Z](-?[a-zA-Z0-9])*(\.[a-zA-Z](-?[a-zA-Z0-9])*)+${0,100}");
            Match mEmailValid = rEmailValid.Match(email);
            if (!mEmailValid.Success)
            {
                return 31;
            }

            /*Address*/
            else if (address.Length > 2000)
            {
                return 50;
            }

            return 1;
        }
        #endregion

        /*Return:
         * 0    : Success
         * -99  : Error
         */
        public int changePassword(string username, string newPassword)
        {
            try
            {
                string hash;
                using (MD5 md5Hash = MD5.Create())
                {
                    SecurityHash secure = new SecurityHash();
                    hash = secure.GetMd5Hash(md5Hash, newPassword);
                }
                int isChangePassword = db.PC_Users_Upd_ChangePass(username, hash);
                return isChangePassword;
            }
            catch(Exception ex)
            {
                return -99;
            }
        }

        /*
         * 1    : success
         * 20   : Password input is null or not have value
         * 21   : Password is less than 5 character
         * 22   : Password is greater than 100 character
         * 23   : Password is not valid, Valid: [a-zA-Z0-9@!#$\'%^&*`~]
         * 24   : Password and repassword is not match
         * 25   : Old Password is null or not have value
         * 26   : Old Password is not correct
         */
        public int changePassValid(string username,string oldPassword, string newPassword, string rePassword)
        {

            /*PASSWORD*/

            if (String.IsNullOrEmpty(oldPassword))
            {
                return 25;
            }
            else
            { //Check old is correct
                var pass = db.PC_Users_Login(username);
                foreach(var i in pass)
                {
                    using(MD5 md5hash = MD5.Create())
                    {
                        SecurityHash secure = new SecurityHash();
                        bool isHash = secure.VerifyMd5Hash(md5hash, oldPassword, i.PassWord);
                        if (!isHash)
                        {
                            return 26;
                        }
                    }
                }

            }

            if (String.IsNullOrEmpty(newPassword))
            {
                return 20;
            }
            else if (newPassword.Length < 8)
            {
                return 21;
            }
            else if (newPassword.Length > 50)
            {
                return 22;
            }

            Regex rPasswordValid = new Regex(@"[a-zA-Z0-9@!#$\'%^&*`~]{0,100}");
            Match mPasswordValid = rPasswordValid.Match(newPassword);
            if (!mPasswordValid.Success)
            {
                return 23;
            }
            else if (!newPassword.Equals(newPassword))
            {
                return 24;
            }

            return 1;
        }

        /* Return:
         * null                     : There is an error
         * .ToList().Count > 0      : Success
         * .ToList().Count <= 0     : There are not any values
         */
        public List<PC_UsersShow_GetOneResult> getUser(string username)
        {
            try
            {
                var user = db.PC_UsersShow_GetOne(username).ToList();
                return user;
            }
            catch(Exception ex)
            {
                return null;
            }
        }

    }
}